/*
 *  @Title TreeJsonFormat.java
 *  @Package： com.phoenix.core.tree
 *  Copyright (c) 2017 by 江苏深南互联网金融信息服务有限公司  All right reserved
 */
package com.phoenix.core.tree;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.springframework.stereotype.Service;

/**
 *  @ClassName TreeJsonFormat
 *  @Description 内存树转换格式数据
 *  @author liuwei
 *  @version 1.0
 *  @date 2017年4月22日
 */
@Service("treeformat")
public class TreeJsonFormat implements TreeFormat {

	private final String jbegin = "{", jend = "}", jsbegin = "\"children\":[", jsend = "]", jsplit = ",",
			idstr = "\"id\":", textstr = "\"text\":", linkstr = "\"link\":", iocnstr = "\"iconClass\":",
			leafstr = "\"leaf\":";

	private Map<String, Integer> counstack = null;

	private JcStack<Iterator<TreeNode>> treestack = null;

	private Map<String, StringBuffer> treeBuffer = null;

	private JcStack<TreeNode> loststack = null;

	private Map<String, Boolean> had = null;

	/** 得到叶子节点的json格式数据 */
	public StringBuffer getLeafNode(TreeNode node) {
		StringBuffer jsonbf = new StringBuffer(50);
		jsonbf.append(jbegin);
		jsonbf.append(idstr);
		jsonbf.append("\"" + node.getId() + "\"");
		jsonbf.append(jsplit);
		jsonbf.append(textstr);
		jsonbf.append("\"" + node.getNodeValue() + "\"");
		jsonbf.append(jsplit);
		jsonbf.append(linkstr);
		jsonbf.append("\"" + node.getLink() + "\"");
		if (node.getIcon() != null && !"".equals(node.getIcon())) {
			jsonbf.append(jsplit);
			jsonbf.append(iocnstr);
			jsonbf.append("\"" + node.getIcon() + "\"");
		}
		jsonbf.append(jsplit);
		jsonbf.append(leafstr);
		jsonbf.append(node.getSize() == 0);
		jsonbf.append(jend);
		return jsonbf;
	}

	/** 得到叶子节点的json格式数据 */
	public StringBuffer getMenuLeafNode(TreeNode node) {
		StringBuffer jsonbf = new StringBuffer(50);
		jsonbf.append(jbegin);
		jsonbf.append(idstr);
		jsonbf.append("\"" + node.getId() + "\"");
		jsonbf.append(jsplit);
		jsonbf.append(textstr);
		jsonbf.append("\"" + node.getNodeValue() + "\"");
		if (node.getLink() != null) {
			jsonbf.append(jsplit);
			jsonbf.append(linkstr);
			jsonbf.append("\"" + node.getLink() + "\"");
		}
		if (node.getList() != null && node.getList().size() > 0) {
			jsonbf.append(jsplit);
			jsonbf.append("\"children\":[");
			for (int i = 0; i < node.getList().size(); i++) {
				jsonbf.append(jbegin);
				jsonbf.append(idstr);
				jsonbf.append("\"" + node.getList().get(i).getId() + "\"");
				jsonbf.append(jsplit);
				jsonbf.append(textstr);
				jsonbf.append("\"" + node.getList().get(i).getNodeValue() + "\"");
				jsonbf.append(jsplit);
				jsonbf.append(linkstr);
				jsonbf.append("\"" + node.getList().get(i).getLink() + "\"");
				jsonbf.append(jend);
				if (i != node.getList().size() - 1) {
					jsonbf.append(jsplit);
				}
			}
			jsonbf.append("]");
		}
		jsonbf.append(jend);
		return jsonbf;
	}

	/** 得到树枝节点的json格式数据 */
	public StringBuffer getBranchNode(TreeNode node, String nodeStr, String childs) {
		StringBuffer jsonbf = new StringBuffer();
		if (nodeStr.indexOf(jsbegin) > 0) {
			String tempchild = nodeStr.substring(nodeStr.indexOf(jsbegin) + 12, nodeStr.lastIndexOf(jsend));
			jsonbf.append(jbegin);
			jsonbf.append(idstr);
			jsonbf.append("\"" + node.getId() + "\"");
			jsonbf.append(jsplit);
			jsonbf.append(textstr);
			jsonbf.append("\"" + node.getNodeValue() + "\"");
			jsonbf.append(jsplit);
			jsonbf.append(jsbegin);
			jsonbf.append(tempchild);
			jsonbf.append(jsplit);
			jsonbf.append(childs);
			jsonbf.append(jsend);
			jsonbf.append(jend);
		} else {
			jsonbf.append(jbegin);
			jsonbf.append(idstr);
			jsonbf.append("\"" + node.getId() + "\"");
			jsonbf.append(jsplit);
			jsonbf.append(textstr);
			jsonbf.append("\"" + node.getNodeValue() + "\"");
			jsonbf.append(jsplit);
			jsonbf.append(jsbegin);
			jsonbf.append(childs);
			jsonbf.append(jsend);
			jsonbf.append(jend);
		}
		return jsonbf;
	}

	/**
	 * 根据传入内存树格式化
	 */
	synchronized public StringBuffer treeDataFormat(TreeNode treeNode, Map<String, TreeNode> treeMp) {
		if (treeMp.isEmpty())
			return new StringBuffer();
		treestack = new JcStack<Iterator<TreeNode>>();
		counstack = new HashMap<String, Integer>();
		loststack = new JcStack<TreeNode>();
		treeBuffer = new HashMap<String, StringBuffer>();
		had = new HashMap<String, Boolean>();
		treestack.push(treeNode.iterator());
		loststack.push(treeNode);
		treeBuffer.put(treeNode.getId(), getLeafNode(treeNode));
		int i = 0;
		TreeNode pa = null;
		while (printhasNext()) {
			i++;
			Iterator<TreeNode> it = treestack.peek();
			TreeNode next = it.next();
			treeBuffer.put(next.getId(), getLeafNode(next));
			counstack.put(next.getId(), next.getSize());
			if (next.getSize() > 0) {
				treestack.push(next.iterator());
				loststack.push(next);
				i = 0;
			} else {
				Integer ii = counstack.get(next.getParentId());
				if (ii != null) {
					if (i == ii.intValue()) {
						pa = treeMp.get(next.getParentId());
						getParent(pa, pa.getList());
						i = 1;
					}
				}
			}
		}
		getLost();
		StringBuffer rtn = treeBuffer.get(treeNode.getId());
		treestack = null;
		counstack = null;
		loststack = null;
		treeBuffer = null;
		had = null;
		return rtn == null ? new StringBuffer() : rtn;
	}

	private void getParent(TreeNode parent, List<TreeNode> list) {
		StringBuffer temppaBuffer = null;
		StringBuffer paBuffer = null;
		had.put(parent.getId(), Boolean.TRUE);
		for (TreeNode tree : list) {
			temppaBuffer = treeBuffer.get(parent.getId());
			if (temppaBuffer == null || temppaBuffer.toString().equals("")) {
				continue;
			}
			if (treeBuffer.containsKey(tree.getId())) {
				paBuffer = getBranchNode(parent, temppaBuffer.toString(), treeBuffer.get(tree.getId()).toString());
				treeBuffer.put(parent.getId(), paBuffer);
			}
		}
	}

	private void getLost() {
		TreeNode lost = null;
		Boolean flag = null;
		while (loststack.isEmpty() == false) {
			lost = loststack.pop();
			flag = had.get(lost.getId());
			if (flag != null) {
				continue;
			}
			getParent(lost, lost.getList());
		}
	}

	private boolean printhasNext() {
		if (treestack.isEmpty()) {
			return Boolean.FALSE;
		} else {
			Iterator<TreeNode> it = treestack.peek();
			if (it.hasNext()) {
				return Boolean.TRUE;
			} else {
				treestack.pop();
				return printhasNext();
			}
		}
	}

	@Override
	public StringBuffer treeDataFormat(TreeNode treeNode, Map<String, TreeNode> treeMp, String condition, int type) {
		return null;
	}

}
